#pragma once

// Local
#include "D3D11Client.h"
#include "TerrainManager.h"


#define NODATA 0xFF
#define NOTILE 0xFFFFFFFF
#define NOTILE64 0xFFFFFFFFFFFFFFFFU
#define TERRAIN_TEXTURE_FOLDER "Terrain\\"
//#define TILE_NVTX 66U//18U
//#define TILE_VTXCNT (TILE_NVTX+1)*(TILE_NVTX+1)// 1225U//361U
//#define TILE_VTXCNT_R ((TILE_NVTX+1)*(TILE_NVTX+1) - ((TILE_NVTX+1)*TILE_NVTX)/2)// 630U//190U
//#define TILE_IDXCNT 6*TILE_NVTX*TILE_NVTX		// 6936U//1944U
//#define TILE_IDXCNT_R TILE_NVTX*TILE_NVTX*3		//3468U//972U

//TILEDESC1 flags:
#define SPECULAR	2U
#define LIGHTS		4U
#define LOAD_NORM	8U
#define LOAD_HEIGHT 16U
#define LOAD_LCOVER 32U
#define OLDIDX		64U
#define LOAD_TEX	128U
#define RECOMPUTEBS	256U
#define REFRESH_TEX	512U

#define MAX_RESOLUTION 18	//maximum tile mesh resolution

#define HMAP_SIDE 65U
#define HMAP_NPIXEL 4225U
#define HMAP_DIM 64.0f
#define HMAP_DIF 0.015625f

#define LCMAP_SIDE 65U
#define LCMAP_NPIXEL 4225U

void MatrixRotY1( D3DXMATRIX *out, float angle );
void read_callback( png_structp png_ptr, png_bytep to_lib, png_size_t lenght );
UINT8 GetMonth( double MJD );



//============================================================================
//				Loading of textures
//============================================================================

#define MAXLOADQUEUE 10

class TileLoader {
	friend class TerrainManager;

	typedef struct LOADINGPARAM {
		TILEDESC1 *td;
		TerrainManager *TM;
	} LOADINGPARAM;

public:
	TileLoader();
	~TileLoader();

	//creates new TILEDESC1 struct and set parent-tile bounding values
	//(bounding sphere will be updated after loading/generation of detailed heightmap)
	bool LoadTile( TerrainManager *TM, TILEDESC1 *tile );

	//loads textures, specular, normal, LCC maps and heightmaps
	static DWORD WINAPI LoadingProc( void *data );

private:
	//loading of diffuse tile texture/specular mask/normal map
	static bool LoadTexture( char *fname, UINT64 ofs, ID3D11ShaderResourceView **out );
	//65x65 PNG compressed SINT16 tiles
	static bool LoadHeightmap( char *fname, UINT64 ofs, INT16 *A, ID3D11ShaderResourceView **out );
	//65x65 PNG compressed UINT8 tiles
	static bool LoadLandCoverMap( char *fname, UINT32 ofs, ID3D11ShaderResourceView **out );

	//queue of tiles to be loaded
	static std::queue<LOADINGPARAM> queue;

	//threading vars
	HANDLE hLoading;	//loading thread handle
	DWORD dwLoading;	//loading thread ID

	static CRITICAL_SECTION LoadingCS;
};

/*
										m./px.
L1	1			64			64			626,747 m
L2	1			128			128			313,373 m
L3	1			256			256			156,686 m
L4	2			512			256			78,343 m
L5	8			1,024		512			39,171 m
L6	24			2,048		1,024		19,586 m				NMAP[L6]
L7	100			4,096		2,048		9,792 m		73.6 km		NMAP[L7]
L8	364			8,192		4,096		4,896 m		36.8 km		NMAP[L8]
L9	1,456		16,384		8,192		2,448 m		18.4 km		NMAP[L9]
L10	5,824		32,768		16,384		1,224 m		9.2 km		NMAP[L10]	GTOPO30
L11	23,296		65,536		32,768		612	m		4.6 km
L12	93,184		131,072		65,536		306 m		2.3 km
L13	372,736		262,144		131,072		153 m		1.15 km
L14	1,490,944	524,288		262,144		76 m		576 m
L15	5,963,776	1,048,576	524,288		38 m		288 m
L16	23,855,104	2,097,152	1,048,576	19 m		144 m
L17 95,420,416	4,194,304	2,097,152	9.6 m		72 m
L18	381,681,664	8,388,608	4,194,304	4.8 m		36 m

diffuse
normal
height

//Tile rendering settings:
typedef struct TILERENDERSPEC {
	TILEDESC1 *td;		//tiledesc struct
	D3DXMATRIX mWorld;	//world matrix
	TILETEX tex;
	TEXCRDRANGE1 range_tex;	//acual range of texcoords
	TEXCRDRANGE1 range_ntex;
	TEXCRDRANGE1 range_htex;
	bool top;			//true for polar tiles [reduced number of triangles => different vertex data]
	UINT8 lvl;		//required for mesh generation in shader
	UINT
		ilat, nlat, nlng;
	float cnt_dist;		//distance of tile center from camera
	float bs_dist;		//distance of bounding sphere border from camera
} TILERENDERSPEC;*/
